<template>
  <div class="step1">
    <div class="step1-form" v-if="!isCustomForm">
      <BasicForm @register="register" />
    </div>
    <Divider v-if="designType === 'code' && !isFormGenerator && !isCustomForm" />
    <template v-if="designType === 'code' && !isFormGenerator">
      <div v-for="(tableConfig, index) in generatorConfig?.tableStructureConfigs" :key="index">
        <a-table
          :columns="tableColumns"
          :data-source="[tableConfig]"
          :pagination="false"
          :defaultExpandAllRows="true"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.dataIndex === 'tableName'">
              <a-input
                v-model:value="record.tableName"
                :placeholder="t('请填写数据表名称')"
                @change="changeComponentName(record, 'table')"
                @blur="handleBlur(record)"
              />
            </template>
            <template v-else-if="column.dataIndex === 'isMain'">
              <span>
                <a-tag :color="record.isMain ? 'blue' : 'orange'">
                  {{ record.isMain ? t('主表') : t('附表') }}
                </a-tag>
              </span>
            </template>
            <template v-else-if="column.dataIndex === 'tableComment'">
              <a-input v-model:value="record.tableComment" :placeholder="t('请填写备注')" />
            </template>
          </template>
          <template #expandedRowRender>
            <a-table
              :columns="fieldColumns"
              :data-source="tableConfig.tableFieldConfigs"
              :pagination="false"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.dataIndex === 'fieldName'">
                  <a-input
                    v-model:value="record.fieldName"
                    :placeholder="t(`请填写{title}`, { title: column.title })"
                    @change="changeComponentName(record, 'field')"
                    :disabled="record.key === 'rule_user_id'"
                  />
                </template>
                <template v-else-if="column.dataIndex === 'fieldLength'">
                  <a-input
                    v-model:value.number="record.fieldLength"
                    :placeholder="t('请填写字段长度')"
                    :disabled="record.fieldType !== 0"
                  />
                </template>
                <template v-else-if="column.dataIndex === 'fieldComment'">
                  <a-input
                    v-model:value.number="record.fieldComment"
                    :placeholder="t('请填写备注')"
                    :disabled="record.key === 'rule_user_id'"
                  />
                </template>
                <template v-else-if="column.dataIndex === 'fieldType'">
                  <a-select
                    v-model:value="record.fieldType"
                    style="width: 100%"
                    :placeholder="t('请选择数据格式')"
                    :disabled="record.key === 'rule_user_id'"
                    allowClear
                    @change="(value) => handleTypeChange(value, record)"
                  >
                    <a-select-option
                      :value="type.value"
                      v-for="(type, idx) in fieldTypeList"
                      :key="idx"
                    >
                      {{ type.label }}
                    </a-select-option>
                  </a-select>
                </template>
              </template>
            </a-table>
          </template>
        </a-table>
      </div>
    </template>
    <TableNameModal @register="registerTableName" @success="handleEditSuccess" />
  </div>
</template>
<script lang="ts" setup>
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { Divider } from 'ant-design-vue';
  import { TableNameModal } from '/@/components/CreateCodeStep';
  import { onMounted, inject, computed, ref, Ref } from 'vue';
  import { debounce, cloneDeep, random, snakeCase } from 'lodash-es';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { validateTableName } from '/@/api/system/generator';
  import { getAuthList } from '/@/api/system/authorize';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useModal } from '/@/components/Modal';
  const { t } = useI18n();
  const [registerTableName, { openModal, closeModal }] = useModal();
  const validateTable = ref(false);
  const emit = defineEmits(['validateTable']);
  const { notification } = useMessage();
  const dataAuthPlaceholder = computed(() => {
    return generatorConfig!.outputConfig!.isDataAuth
      ? t('请选择已有通用数据权限')
      : t('请先启用数据权限');
  });
  const dataAuthHelpMessage = `
  1.启用数据权限会判断主表是否包含RuleUserlD字段如果存在，则不进行表结构修改，如果不存在，则会对主表进行字段添加。
  2.RuleUserlD主要用来控制每一条记录的权限所属人新增时，默认将当前登录认作为权限所属人。
  3.在表单设计中会添加“批量设置权限所属人”功能启用后，拥有该按钮权限的人员可以设置每一条记录的权限所属人。
    `;
  const formSchemaCode: FormSchema[] = [
    {
      field: 'className',
      label: t('功能名称'),
      required: true,
      component: 'Input',
      title: t('基本信息'),
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能名称'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.outputConfig!.className = val.target.value;
          const { outputConfig, tableStructureConfigs } = generatorConfig!;
          tableStructureConfigs?.map((item) => {
            const name = snakeCase(outputConfig!.className!);
            const tableName = isFieldUpper.value ? name.toUpperCase() : name;
            item.tableName = item.isMain
              ? tableName
              : isFieldUpper.value
              ? `${tableName}_CHILD_${random(1000, 9999)}`
              : `${tableName}_child_${random(1000, 9999)}`;
            changeComponentName(item, 'table');
          });
        }, 200),
      },
    },
    {
      field: 'comment',
      label: t('功能描述'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能描述'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.outputConfig!.comment = val.target.value;
        }, 200),
      },
    },
    {
      field: 'outputArea',
      label: t('功能模块'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择功能模块'),
        itemId: '1419276800524423333',
        onChange: debounce((_, obj) => {
          if (obj) {
            generatorConfig!.outputConfig!.outputArea = obj.id;
            generatorConfig!.outputConfig!.outputValue = obj.value;
          }
        }, 200),
      },
      colProps: { span: 12 },
    },
    {
      field: 'remarks',
      label: t('备注'),
      component: 'Input',
      required: false,
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写备注'),
        onChange: debounce((val) => {
          generatorConfig!.outputConfig!.remarks = val.target.value;
          generatorConfig!.tableStructureConfigs?.map(
            (item) => (item.tableComment = item.isMain ? val.target.value : item.tableComment),
          );
        }, 200),
      },
    },
    {
      field: 'isDataAuth',
      label: t('数据权限'),
      component: 'Switch',
      required: false,
      colProps: { span: 12 },
      helpMessage: dataAuthHelpMessage,
      helpComponentProps: { maxWidth: '400px' },
      componentProps: {
        checkedValue: true,
        unCheckedValue: false,
        onChange: (val) => {
          if (!val) {
            setFieldsValue({ dataAuthList: [] });
            generatorConfig!.outputConfig!.dataAuthList = [];
            if (generatorConfig?.tableStructureConfigs?.length) {
              generatorConfig.tableStructureConfigs[0].tableFieldConfigs =
                generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.filter(
                  (x) => x.key !== 'rule_user_id',
                );
            }
          } else {
            const hasRuleUserField =
              generatorConfig?.tableStructureConfigs?.length &&
              generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.find(
                (x) => x.key === 'rule_user_id',
              );
            if (hasRuleUserField) return;
            generatorConfig?.tableStructureConfigs?.length &&
              generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.push({
                key: 'rule_user_id',
                fieldName: 'rule_user_id',
                fieldLength: 500,
                fieldType: 7,
                fieldComment: t('数据权限所属人ID'),
              });
          }
          generatorConfig!.outputConfig!.isDataAuth = val;
        },
      },
    },
    {
      field: 'dataAuthList',
      label: t('权限选择'),
      component: 'ApiSelect',
      required: false,
      colProps: { span: 12 },
      componentProps: {
        mode: 'multiple',
        placeholder: dataAuthPlaceholder,
        api: getAuthList,
        labelField: 'name',
        valueField: 'id',
        getPopupContainer: () => document.body,
        onChange: (val) => {
          generatorConfig!.outputConfig!.dataAuthList = val;
        },
      },
      dynamicDisabled: ({ values }) => {
        return !values.isDataAuth;
      },
    },
  ];

  const formSchemaTemplate: FormSchema[] = [
    {
      field: 'className',
      label: t('功能名称'),
      required: true,
      component: 'Input',
      title: t('基本信息'),
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能名称'),
        onChange: (val: ChangeEvent) => {
          generatorConfig!.outputConfig!.className = val.target.value;
          const { outputConfig, tableStructureConfigs } = generatorConfig!;
          tableStructureConfigs?.map((item) => {
            const name = snakeCase(outputConfig!.className!);
            const tableName = isFieldUpper.value ? name.toUpperCase() : name;
            item.tableName = item.isMain
              ? tableName
              : isFieldUpper.value
              ? `${tableName}_CHILD_${random(1000, 9999)}`
              : `${tableName}_child_${random(1000, 9999)}`;
            changeComponentName(item, 'table');
          });
        },
      },
    },
    {
      field: 'comment',
      label: t('功能描述'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能描述'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.outputConfig!.comment = val.target.value;
        }, 200),
      },
    },
    {
      field: 'outputArea',
      label: t('功能模块'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择功能模块'),
        itemId: '1419276800524423333',
        onChange: debounce((_, obj) => {
          if (obj) {
            generatorConfig!.outputConfig!.outputArea = obj.id;
            generatorConfig!.outputConfig!.outputValue = obj.value;
          }
        }, 200),
      },
      colProps: { span: 12 },
    },
    {
      field: 'remarks',
      label: t('备注'),
      component: 'Input',
      required: false,
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写备注'),
        onChange: debounce((val) => {
          generatorConfig!.outputConfig!.remarks = val.target.value;
          generatorConfig!.tableStructureConfigs?.map(
            (item) => (item.tableComment = item.isMain ? val.target.value : item.tableComment),
          );
        }, 200),
      },
    },
    {
      field: 'isDataAuth',
      label: t('数据权限'),
      component: 'Switch',
      required: false,
      colProps: { span: 12 },
      helpMessage: dataAuthHelpMessage,
      helpComponentProps: { maxWidth: '400px' },
      componentProps: {
        checkedValue: true,
        unCheckedValue: false,
        onChange: (val) => {
          if (!val) {
            setFieldsValue({ dataAuthList: [] });
            generatorConfig!.outputConfig!.dataAuthList = [];
            generatorConfig?.tableStructureConfigs?.length &&
              generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.map(
                (x) => x.key !== 'rule_user_id',
              );
          } else {
            const hasRuleUserField =
              generatorConfig?.tableStructureConfigs?.length &&
              generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.find(
                (x) => x.key === 'rule_user_id',
              );
            if (hasRuleUserField) return;
            generatorConfig?.tableStructureConfigs?.length &&
              generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.push({
                key: 'rule_user_id',
                fieldName: 'rule_user_id',
                fieldLength: 500,
                fieldType: 7,
                fieldComment: t('数据权限所属人ID'),
              });
          }
          generatorConfig!.outputConfig!.isDataAuth = val;
        },
      },
    },
    {
      field: 'dataAuthList',
      label: t('权限选择'),
      component: 'ApiSelect',
      required: false,
      colProps: { span: 12 },
      componentProps: {
        mode: 'multiple',
        placeholder: dataAuthPlaceholder,
        api: getAuthList,
        labelField: 'name',
        valueField: 'id',
        getPopupContainer: () => document.body,
        onChange: (val) => {
          generatorConfig!.outputConfig!.dataAuthList = val;
        },
      },
      dynamicDisabled: ({ values }) => {
        return !values.isDataAuth;
      },
    },
  ];
  const generatorSchema: FormSchema[] = [
    {
      field: 'className',
      label: t('功能名称'),
      required: true,
      component: 'Input',
      title: t('基本信息'),
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能名称'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.outputConfig!.className = val.target.value;
        }, 200),
      },
    },
    {
      field: 'comment',
      label: t('功能描述'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能描述'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.outputConfig!.comment = val.target.value;
        }, 200),
      },
    },
    {
      field: 'outputArea',
      label: t('功能模块'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择功能模块'),
        itemId: '1419276800524423333',
        onChange: debounce((_, obj) => {
          if (obj) {
            generatorConfig!.outputConfig!.outputArea = obj.id;
            generatorConfig!.outputConfig!.outputValue = obj.value;
          }
        }, 200),
      },
      colProps: { span: 12 },
    },
    {
      field: 'remarks',
      label: t('备注'),
      component: 'Input',
      required: false,
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写备注'),
        onChange: debounce((val) => {
          generatorConfig!.outputConfig!.remarks = val.target.value;
        }, 200),
      },
    },
  ];

  const tableColumns = [
    {
      title: t('数据表名称'),
      dataIndex: 'tableName',
    },
    {
      title: t('数据表类别'),
      dataIndex: 'isMain',
      align: 'center',
      width: 200,
    },
    {
      title: t('备注'),
      dataIndex: 'tableComment',
      align: 'center',
    },
  ];

  const fieldColumns = [
    {
      title: t('字段名'),
      dataIndex: 'fieldName',
      width: 500,
    },
    {
      title: t('字段长度'),
      dataIndex: 'fieldLength',
      align: 'center',
    },
    {
      title: t('数据格式'),
      dataIndex: 'fieldType',
      align: 'center',
    },
    {
      title: t('备注'),
      dataIndex: 'fieldComment',
    },
  ];

  const fieldTypeList = [
    {
      label: t('短文本'),
      value: 0,
    },
    {
      label: t('长文本（适用于多行文本等组件）'),
      value: 1,
    },
    {
      label: t('整数'),
      value: 2,
    },
    {
      label: t('小数'),
      value: 3,
    },
    {
      label: t('日期'),
      value: 4,
    },
    {
      label: t('日期时间'),
      value: 5,
    },
    {
      label: t('外键'),
      value: 6,
    },
    {
      label: t('长整数'),
      value: 7,
    },
    {
      label: t('时间'),
      value: 8,
    },
  ];

  const generatorConfig = inject<GeneratorConfig>('generatorConfig');
  const widgetForm = inject<any>('widgetForm');
  let mainTableName = inject<any>('mainTableName', '');
  const designType = inject<string>('designType', '');
  const isCustomForm = inject<boolean>('isCustomForm', false);
  const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));

  const props = defineProps({
    //是否是自定义表单生成代码
    isFormGenerator: {
      type: Boolean,
      default: false,
    },
    //是否是编辑状态
    isUpdate: {
      type: Boolean,
      default: false,
    },
    //新增时的表名集合
    beforeTableNames: {
      type: Array,
      default: () => [],
    },
  });

  const [register, { validate, setFieldsValue, clearValidate }] = useForm({
    labelWidth: 100,
    schemas: props.isFormGenerator
      ? generatorSchema
      : designType === 'code'
      ? formSchemaCode
      : formSchemaTemplate,
    showActionButtonGroup: false,
  });
  onMounted(() => {
    const { outputConfig } = generatorConfig!;
    if (
      !isCustomForm &&
      (outputConfig?.className || outputConfig?.comment || outputConfig?.outputArea)
    ) {
      setFieldsValue({
        className: outputConfig?.className,
        comment: outputConfig?.comment,
        outputArea: outputConfig?.outputArea,
        isDataAuth: outputConfig?.isDataAuth,
        dataAuthList: outputConfig?.dataAuthList,
      });
      clearValidate();
    }
  });
  const changeComponentInfo = (list, type, fieldKey, name, tableKey, rangField?) => {
    const isTable = type === 'table';
    if (generatorConfig?.formJson.hiddenComponent?.length) {
      generatorConfig?.formJson.hiddenComponent?.map((component: any) => {
        if (component.key === fieldKey) {
          isTable ? (component.bindTable = name) : (component.bindField = name);
        }
      });
      widgetForm!.value.hiddenComponent = cloneDeep(generatorConfig?.formJson.hiddenComponent);
    }
    list?.map((component: any) => {
      if (component.type === 'form' || component.type === 'one-for-one') {
        if (isTable && component.key === tableKey) {
          component.bindTable = name;
        }
        if (component.children.length) {
          component.children.map((subComponent: any) => {
            if (['tab', 'grid', 'card'].includes(subComponent.type)) {
              subComponent.bindTable = name;
              for (const subChild of subComponent.layout!) {
                changeComponentInfo(subChild.list, type, fieldKey, name, tableKey, rangField);
              }
            } else if (subComponent.key === fieldKey) {
              isTable ? (subComponent.bindTable = name) : (subComponent.bindField = name);
            }
          });
        }
      } else if (component.key === fieldKey) {
        //修改主表名
        mainTableName!.value = name;
        if (['time-range', 'date-range'].includes(component.type)) {
          isTable ? (component.bindTable = name) : (component[rangField] = name);
        } else {
          isTable ? (component.bindTable = name) : (component.bindField = name);
        }
      } else if (['tab', 'grid', 'card'].includes(component.type)) {
        for (const child of component.layout!) {
          changeComponentInfo(child.list, type, fieldKey, name, tableKey, rangField);
        }
      }
    });
    widgetForm!.value.list = cloneDeep(generatorConfig!.formJson.list); //表单设计页面绑定表和字段需要同步修改
  };

  const changeComponentName = (record, type) => {
    const rangField = record.fieldStartName
      ? 'bindStartTime'
      : record.fieldEndName
      ? 'bindEndTime'
      : '';
    if (type === 'table') {
      const name = snakeCase(record.tableName);
      record.tableFieldConfigs.forEach((item) => {
        changeComponentInfo(
          generatorConfig?.formJson.list,
          'table',
          item.key,
          isFieldUpper.value ? name.toUpperCase() : name,
          record.key,
        );
      });
    } else {
      changeComponentInfo(
        generatorConfig?.formJson.list,
        'field',
        record.key,
        record.fieldName,
        '',
        rangField,
      );
    }
  };

  const handleBlur = (record) => {
    const name = snakeCase(record.tableName);
    record.tableName = isFieldUpper.value ? name.toUpperCase() : name;
  };

  const handleTypeChange = (value, record) => {
    if (value !== 0) {
      record.fieldLength = null;
    } else {
      record.fieldLength = 500;
    }
  };

  //验证当前步骤的数据
  const validateStep = async (): Promise<boolean> => {
    try {
      const { tableStructureConfigs, outputConfig } = generatorConfig!;

      if (!isCustomForm) {
        await validate();

        if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(outputConfig!.className!)) {
          notification.error({
            message: t('提示'),
            description: t('功能名称只能是数字和字母组成，必须以英文字母开头'),
          });
          return false;
        }
      }
      if (props.isFormGenerator) return true;
      const tableNames: string[] = tableStructureConfigs!.map((x) => x.tableName);

      const reg = /^[a-zA-Z0-9_]*$/;
      //判断表名是否符合要求
      const isTableNotSuccess = tableStructureConfigs?.some((config: any) => {
        return !reg.test(config.tableName);
      });
      if (isTableNotSuccess) {
        notification.error({
          message: t('提示'),
          description: '表名只能包括字母、数字、下划线',
        }); //提示消息
        return false;
      }
      //判断字段名是否符合要求
      const isFieldNotSuccess = tableStructureConfigs?.some((config: any) => {
        const isNotPassValidation = config.tableFieldConfigs.some((fieldConfig: any) => {
          return !reg.test(fieldConfig.fieldName) || fieldConfig.fieldName.length > 30;
        });
        return isNotPassValidation;
      });
      if (isFieldNotSuccess) {
        notification.error({
          message: t('提示'),
          description:
            '字段名必须以小写字母开头，只能包括小写字母、数字、下划线，并且不能超过30个字符',
        }); //提示消息
        return false;
      }
      const notHasRepeatName = tableStructureConfigs?.every((config) => {
        const nameArr = config.tableFieldConfigs.map((x) => x.fieldName);
        return [...new Set(nameArr)].length === nameArr.length;
      });
      if (!notHasRepeatName) {
        notification.error({
          message: t('提示'),
          description: t('同一个表内，不能有相同字段名'),
        }); //提示消息
        return false;
      }
      const testTableNames = tableNames.filter((x) => {
        return !props.beforeTableNames.includes(x);
      });
      const params = {
        id: designType === 'code' ? generatorConfig!.databaseId! : 'master',
        tableNames: props.isUpdate ? testTableNames.toString() : tableNames.toString(),
      };
      if (!props.isUpdate || (!props.isUpdate && testTableNames.length)) {
        await validateTableName(params);
      }

      if (props.isUpdate) {
        if (!validateTable.value) {
          openModal();
          return false;
        }
      }
    } catch (error) {
      return false;
    }
    validateTable.value = false;
    return true;
  };
  async function handleEditSuccess() {
    validateTable.value = true;
    closeModal();
    emit('validateTable');
  }
  defineExpose({ validateStep });
</script>
<style lang="less" scoped>
  .step1 {
    h3 {
      margin: 0 0 12px;
      font-size: 16px;
      line-height: 32px;
      color: @text-color;
    }

    h4 {
      margin: 0 0 4px;
      font-size: 14px;
      line-height: 22px;
      color: @text-color;
    }

    p {
      color: @text-color;
    }
  }

  .pay-select {
    width: 20%;
  }

  .pay-input {
    width: 70%;
  }

  :deep(.ant-tag-orange),
  :deep(.ant-tag-blue) {
    background: #fff;
    padding: 3px 12px;
    font-size: 13px;
  }

  :deep(.ant-spin-nested-loading) {
    overflow: hidden; //去掉表格嵌套子表滚动条
  }
</style>
